//
//  GesturePasswordView.swift
//  AirlineReservation
//
//  Created by Kevin on 2020/2/1.
//  Copyright © 2020 Kevin. All rights reserved.
//

import UIKit

class GesturePasswordView: UIView {
    
    private let ID = "gesture_cell_id"
    // 手势路径
    private var path = UIBezierPath()
    // 存放每次手势路径上的indexPath
    private var passwordIndexPathArr = [IndexPath]()
    // 连线
    private lazy var calayer = CAShapeLayer()
    // 集合视图
    private lazy var collectionView = UICollectionView()
    
    // item背景色 默认浅灰色
    public var itemBackGoundColor:UIColor?
    // item中间圆球的颜色 默认灰色
    public var itemCenterBallColor:UIColor?
    // 线条正常状态的颜色 默认灰色
    public var lineNormalColor:UIColor?
    // 线条错误状态的颜色 默认红色
    public var lineErrorColor:UIColor?
    
    // 密码回调
    public var addPasswordBlock:((_ password:String) -> Void)?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        buildUI()
        setDefaultColor()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        collectionView.frame = bounds
    }
}

extension GesturePasswordView {
    
    private func buildUI() -> Void {
        layer.masksToBounds = true
        // 初始化collectionView
        let layout = UICollectionViewFlowLayout()
        collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
        collectionView.backgroundColor = UIColor.clear
        collectionView.register(GesturePasswordCell.self, forCellWithReuseIdentifier: ID)
        collectionView.dataSource = self
        collectionView.delegate = self
        addSubview(collectionView)
        
        // 初始化手势
        collectionView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(panMethod(pan:))))
        
        //创建中间连线
        calayer.fillColor = UIColor.clear.cgColor
        calayer.lineWidth = 3
        calayer.lineCap = .round
        calayer.lineJoin = .round
        layer.addSublayer(calayer)
    }
    
    private func setDefaultColor() -> Void {
        itemBackGoundColor = UIColor.lightGray
        itemCenterBallColor = UIColor.gray
    }
    
}

extension GesturePasswordView: UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 9
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return itemSpacing()
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return itemSpacing()
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: itemWidth(), height: itemWidth())
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: itemSpacing(), left: itemSpacing(), bottom: itemSpacing(), right: itemSpacing())
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ID, for: indexPath) as! GesturePasswordCell
        cell.gestureSelected = passwordIndexPathArr.contains(indexPath)
        cell.itemBackGoundColor = itemBackGoundColor
        cell.itemCenterBallColor = itemCenterBallColor
        return cell
    }
}

// MARK: 辅助相关
extension GesturePasswordView {
    
    private func itemSpacing() -> CGFloat {
        return bounds.width / 10
    }
    
    private func itemWidth() -> CGFloat {
        return (bounds.width - 4 * itemSpacing()) / 3
    }
    
    // 设置线条正常颜色
    private func setLineNormalColor(normalColor:UIColor) -> Void {
        lineNormalColor = normalColor
        calayer.strokeColor = normalColor.cgColor
    }
    
    // 设置线条错误颜色
    private func setLineErrorColor(color:UIColor) -> Void {
        lineErrorColor = color
    }
    
    // 报错
    public func showError() -> Void {
        calayer.strokeColor = lineErrorColor?.cgColor
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            self.refresh()
        }
    }
    
    public func updateError() -> Void {
        // 禁止布局交互
        isUserInteractionEnabled = false
        // 修改布局颜色
        for i in 0..<collectionView.visibleCells.count {
            let indexPath = IndexPath(item: i, section: 0)
            let cell = collectionView.cellForItem(at: indexPath) as! GesturePasswordCell
            cell.itemBackGoundColor = GESTURE_BG_RED
        }
        itemCenterBallColor = GESTURE_CENTER_RED
        calayer.strokeColor = GESTURE_CENTER_RED.cgColor
        collectionView.reloadData()
        // 自动刷新+颜色重置
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            self.refresh()
            self.itemCenterBallColor = COLOR_BLUE
            // 恢复布局交互
            self.isUserInteractionEnabled = true
        }
    }
    
    // 重置
    func refresh() -> Void {
        // 刷新列表
        passwordIndexPathArr.removeAll()
        collectionView.reloadData()
        // 更新路径
        path.removeAllPoints()
        calayer.path = path.cgPath
        calayer.strokeColor = lineNormalColor?.cgColor
    }
}

// MARK:  手势相关
extension GesturePasswordView {
    
    @objc func panMethod(pan:UIPanGestureRecognizer) -> Void {
        let point = pan.location(in: collectionView)
        switch pan.state {
        case .began:
            gestureBegan()
        case .changed:
            gestureChanged(point: point)
        case .ended:
            gestureEnded()
        default:
            break
        }
    }
    // 手势开始
    func gestureBegan() -> Void {
        refresh()
    }
    
    // 手势变化
    func gestureChanged(point:CGPoint) -> Void {
        updatePasswordIndexPathArr(point: point)
        updateGesturePath(point: point)
    }
    
    // 更新路径上的indexPath
    func updatePasswordIndexPathArr(point:CGPoint) -> Void {
        for indexPath in collectionView.indexPathsForVisibleItems {
            let cell = collectionView.cellForItem(at: indexPath) as! GesturePasswordCell
            if cell.frame.contains(point) {
                if !passwordIndexPathArr.contains(indexPath) {
                    passwordIndexPathArr.append(indexPath)
                    cell.gestureSelected = true
                }
            }
        }
    }
    
    // 绘制手势路径
    func configGesturePath() -> Void {
        path.removeAllPoints()
        for i in 0..<passwordIndexPathArr.count {
            let indexPath = passwordIndexPathArr[i]
            let cell = collectionView.cellForItem(at: indexPath)
            if i == 0 {
                path.move(to: cell!.center)
            }else{
                path.addLine(to: cell!.center)
            }
        }
        calayer.path = path.cgPath
    }
    
    // 更新手势路径
    func updateGesturePath(point:CGPoint) -> Void {
        configGesturePath()
        path.addLine(to: point)
        calayer.path = path.cgPath
    }
    
    // 手势结束
    func gestureEnded() -> Void {
        // 显示手势路径
        configGesturePath()
        // 密码
        var password = ""
        for indexPath in passwordIndexPathArr {
            password = password.appendingFormat("%zd", indexPath.row)
        }
        if let callback = addPasswordBlock {
            callback(password)
        }
    }
}
